<template>
  <div class="menu-page art-full-height">
    <!-- 搜索栏 -->
    <ArtSearchBar
      v-model:filter="formFilters"
      :items="formItems"
      :showExpand="false"
      @reset="handleReset"
      @search="handleSearch"
    ></ArtSearchBar>

    <ElCard class="art-table-card" shadow="never">
      <!-- 表格头部 -->
      <ArtTableHeader
        :showZebra="false"
        v-model:columns="columnChecks"
        @refresh="handleRefresh"
      >
        <template #left>
          <!-- 按钮权限：后端控制模式，使用自定义指令 -->
          <ElButton
            v-auth="'add'"
            @click="showModel('menu', null, true)"
            v-ripple
          >
            添加菜单
          </ElButton>
          <ElButton @click="toggleExpand" v-ripple>
            {{ isExpanded ? "收起" : "展开" }}
          </ElButton>
          <!-- 按钮权限：前端控制模式，使用 hasAuth 方法 -->
          <ElButton
            v-if="hasAuth('add')"
            @click="showModel('menu', null, true)"
            v-ripple
          >
            添加菜单
          </ElButton>
        </template>
      </ArtTableHeader>

      <ArtTable
        ref="tableRef"
        rowKey="path"
        :loading="loading"
        :columns="columns"
        :data="filteredTableData"
        :stripe="false"
      />

      <ElDialog
        :title="dialogTitle"
        v-model="dialogVisible"
        width="700px"
        align-center
      >
        <ElForm ref="formRef" :model="form" :rules="rules" label-width="85px">
          <ElFormItem label="菜单类型">
            <ElRadioGroup v-model="labelPosition" :disabled="disableMenuType">
              <ElRadioButton value="menu" label="menu">菜单</ElRadioButton>
              <ElRadioButton value="button" label="button">权限</ElRadioButton>
            </ElRadioGroup>
          </ElFormItem>

          <template v-if="labelPosition === 'menu'">
            <ElRow :gutter="20">
              <ElCol :span="12">
                <ElFormItem label="菜单名称" prop="name">
                  <ElInput v-model="form.name" placeholder="菜单名称"></ElInput>
                </ElFormItem>
              </ElCol>
              <ElCol :span="12">
                <ElFormItem label="路由地址" prop="path">
                  <ElInput v-model="form.path" placeholder="路由地址"></ElInput>
                </ElFormItem>
              </ElCol>
            </ElRow>
            <ElRow :gutter="20">
              <ElCol :span="12">
                <ElFormItem label="权限标识" prop="label">
                  <ElInput
                    v-model="form.label"
                    placeholder="权限标识"
                  ></ElInput>
                </ElFormItem>
              </ElCol>
              <ElCol :span="12">
                <ElFormItem label="图标" prop="icon">
                  <ArtIconSelector
                    v-model="form.icon"
                    :iconType="iconType"
                    width="100%"
                  />
                </ElFormItem>
              </ElCol>
            </ElRow>

            <ElRow :gutter="20">
              <ElCol :span="12">
                <ElFormItem label="菜单排序" prop="sort" style="width: 100%">
                  <ElInputNumber
                    v-model="form.sort"
                    style="width: 100%"
                    @change="handleChange"
                    :min="1"
                    controls-position="right"
                  />
                </ElFormItem>
              </ElCol>
              <ElCol :span="12">
                <ElFormItem label="外部链接" prop="link">
                  <ElInput
                    v-model="form.link"
                    placeholder="外部链接/内嵌地址(https://www.baidu.com)"
                  ></ElInput>
                </ElFormItem>
              </ElCol>
            </ElRow>

            <ElRow :gutter="20">
              <ElCol :span="5">
                <ElFormItem label="是否启用" prop="isEnable">
                  <ElSwitch v-model="form.isEnable"></ElSwitch>
                </ElFormItem>
              </ElCol>
              <ElCol :span="5">
                <ElFormItem label="页面缓存" prop="keepAlive">
                  <ElSwitch v-model="form.keepAlive"></ElSwitch>
                </ElFormItem>
              </ElCol>
              <ElCol :span="5">
                <ElFormItem label="是否显示" prop="isHidden">
                  <ElSwitch v-model="form.isHidden"></ElSwitch>
                </ElFormItem>
              </ElCol>
              <ElCol :span="5">
                <ElFormItem label="是否内嵌" prop="isMenu">
                  <ElSwitch v-model="form.isIframe"></ElSwitch>
                </ElFormItem>
              </ElCol>
            </ElRow>
          </template>

          <template v-if="labelPosition === 'button'">
            <ElRow :gutter="20">
              <ElCol :span="12">
                <ElFormItem label="权限名称" prop="authName">
                  <ElInput
                    v-model="form.authName"
                    placeholder="权限名称"
                  ></ElInput>
                </ElFormItem>
              </ElCol>
              <ElCol :span="12">
                <ElFormItem label="权限标识" prop="authLabel">
                  <ElInput
                    v-model="form.authLabel"
                    placeholder="权限标识"
                  ></ElInput>
                </ElFormItem>
              </ElCol>
            </ElRow>
            <ElRow :gutter="20">
              <ElCol :span="12">
                <ElFormItem
                  label="权限排序"
                  prop="authSort"
                  style="width: 100%"
                >
                  <ElInputNumber
                    v-model="form.authSort"
                    style="width: 100%"
                    @change="handleChange"
                    :min="1"
                    controls-position="right"
                  />
                </ElFormItem>
              </ElCol>
            </ElRow>
          </template>
        </ElForm>

        <template #footer>
          <span class="dialog-footer">
            <ElButton @click="dialogVisible = false">取 消</ElButton>
            <ElButton type="primary" @click="submitForm()">确 定</ElButton>
          </span>
        </template>
      </ElDialog>
    </ElCard>
  </div>
</template>

<script setup lang="ts">
import { useMenuStore } from "@/store/modules/menu";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage, ElMessageBox, ElTag } from "element-plus";
import { IconTypeEnum } from "@/enums/appEnum";
import { formatMenuTitle } from "@/router/utils/utils";
import ArtButtonTable from "@/components/core/forms/art-button-table/index.vue";
import { useTableColumns } from "@/composables/useTableColumns";
import { ElPopover, ElButton } from "element-plus";
import { AppRouteRecord } from "@/types/router";
import { useAuth } from "@/composables/useAuth";
import { SearchFormItem } from "@/types";

defineOptions({ name: "Menus" });

const { hasAuth } = useAuth();

const { menuList } = storeToRefs(useMenuStore());

const loading = ref(false);

// 定义表单搜索初始值
const initialSearchState = {
  name: "",
  route: "",
};

// 响应式表单数据
const formFilters = reactive({ ...initialSearchState });

// 增加实际应用的搜索条件状态
const appliedFilters = reactive({ ...initialSearchState });

// 重置表单
const handleReset = () => {
  Object.assign(formFilters, { ...initialSearchState });
  Object.assign(appliedFilters, { ...initialSearchState });
  getTableData();
};

// 搜索处理
const handleSearch = () => {
  // 将当前输入的筛选条件应用到实际搜索
  Object.assign(appliedFilters, { ...formFilters });
  getTableData();
};

// 表单配置项
const formItems: SearchFormItem[] = [
  {
    label: "菜单名称",
    prop: "name",
    type: "input",
    config: {
      clearable: true,
    },
  },
  {
    label: "路由地址",
    prop: "route",
    type: "input",
    config: {
      clearable: true,
    },
  },
];

// 构建菜单类型标签
const buildMenuTypeTag = (row: AppRouteRecord) => {
  if (row.children && row.children.length > 0) {
    return "info";
  } else if (row.meta?.link && row.meta?.isIframe) {
    return "success";
  } else if (row.path) {
    return "primary";
  } else if (row.meta?.link) {
    return "warning";
  }
};

// 构建菜单类型文本
const buildMenuTypeText = (row: AppRouteRecord) => {
  if (row.children && row.children.length > 0) {
    return "目录";
  } else if (row.meta?.link && row.meta?.isIframe) {
    return "内嵌";
  } else if (row.path) {
    return "菜单";
  } else if (row.meta?.link) {
    return "外链";
  }
};

// 动态列配置
const { columnChecks, columns } = useTableColumns(() => [
  {
    prop: "meta.title",
    label: "菜单名称",
    minWidth: 120,
    formatter: (row: AppRouteRecord) => {
      return formatMenuTitle(row.meta?.title);
    },
  },
  {
    prop: "type",
    label: "菜单类型",
    formatter: (row: AppRouteRecord) => {
      return h(ElTag, { type: buildMenuTypeTag(row) }, () =>
        buildMenuTypeText(row),
      );
    },
  },
  {
    prop: "path",
    label: "路由",
    formatter: (row: AppRouteRecord) => {
      return row.meta?.link || row.path || "";
    },
  },
  {
    prop: "meta.authList",
    label: "可操作权限",
    formatter: (row: AppRouteRecord) => {
      return h(
        "div",
        {},
        row.meta.authList?.map(
          (item: { title: string; authMark: string }, index: number) => {
            return h(
              ElPopover,
              {
                placement: "top-start",
                title: "操作",
                width: 200,
                trigger: "click",
                key: index,
              },
              {
                default: () =>
                  h("div", { style: "margin: 0; text-align: right" }, [
                    h(
                      ElButton,
                      {
                        size: "small",
                        type: "primary",
                        onClick: () => showModel("button", item),
                      },
                      { default: () => "编辑" },
                    ),
                    h(
                      ElButton,
                      {
                        size: "small",
                        type: "danger",
                        onClick: () => deleteAuth(),
                      },
                      { default: () => "删除" },
                    ),
                  ]),
                reference: () =>
                  h(
                    ElButton,
                    { class: "small-btn" },
                    { default: () => item.title },
                  ),
              },
            );
          },
        ),
      );
    },
  },
  {
    prop: "date",
    label: "编辑时间",
    formatter: () => "2022-3-12 12:00:00",
  },
  {
    prop: "status",
    label: "隐藏菜单",
    formatter: (row) => {
      return h(ElTag, { type: row.meta.isHide ? "danger" : "info" }, () =>
        row.meta.isHide ? "是" : "否",
      );
    },
  },
  {
    prop: "operation",
    label: "操作",
    width: 180,
    formatter: (row: AppRouteRecord) => {
      return h("div", [
        // 这里写两组权限标识判断是为了方便演示，在实际开发中可以删除其中一组
        // 前端模式权限标识
        hasAuth("B_CODE1") &&
          h(ArtButtonTable, {
            type: "add",
            onClick: () => showModel("menu"),
          }),
        hasAuth("B_CODE2") &&
          h(ArtButtonTable, {
            type: "edit",
            onClick: () => showDialog("edit", row),
          }),
        hasAuth("B_CODE3") &&
          h(ArtButtonTable, {
            type: "delete",
            onClick: () => deleteMenu(),
          }),
        // 后端模式权限标识
        hasAuth("add") &&
          h(ArtButtonTable, {
            type: "add",
            onClick: () => showModel("menu"),
          }),
        hasAuth("edit") &&
          h(ArtButtonTable, {
            type: "edit",
            onClick: () => showDialog("edit", row),
          }),
        hasAuth("delete") &&
          h(ArtButtonTable, {
            type: "delete",
            onClick: () => deleteMenu(),
          }),
      ]);
    },
  },
]);

const handleRefresh = () => {
  getTableData();
};

const dialogVisible = ref(false);
const form = reactive({
  // 菜单
  name: "",
  path: "",
  label: "",
  icon: "",
  isEnable: true,
  sort: 1,
  isMenu: true,
  keepAlive: true,
  isHidden: true,
  link: "",
  isIframe: false,
  // 权限 (修改这部分)
  authName: "",
  authLabel: "",
  authIcon: "",
  authSort: 1,
});
const iconType = ref(IconTypeEnum.UNICODE);

const labelPosition = ref("menu");
const rules = reactive<FormRules>({
  name: [
    { required: true, message: "请输入菜单名称", trigger: "blur" },
    { min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "blur" },
  ],
  path: [{ required: true, message: "请输入路由地址", trigger: "blur" }],
  label: [{ required: true, message: "输入权限标识", trigger: "blur" }],
  // 修改这部分
  authName: [{ required: true, message: "请输入权限名称", trigger: "blur" }],
  authLabel: [
    { required: true, message: "请输入权限权限标识", trigger: "blur" },
  ],
});

const tableData = ref<AppRouteRecord[]>([]);

onMounted(() => {
  getTableData();
});

const getTableData = () => {
  loading.value = true;
  setTimeout(() => {
    tableData.value = menuList.value;
    loading.value = false;
  }, 500);
};

// 过滤后的表格数据
const filteredTableData = computed(() => {
  // 深拷贝函数，避免修改原数据
  const deepClone = (obj: any): any => {
    if (obj === null || typeof obj !== "object") return obj;
    if (obj instanceof Date) return new Date(obj);
    if (Array.isArray(obj)) return obj.map((item) => deepClone(item));

    const cloned: any = {};
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        cloned[key] = deepClone(obj[key]);
      }
    }
    return cloned;
  };

  // 递归搜索函数
  const searchMenu = (items: AppRouteRecord[]): AppRouteRecord[] => {
    const results: AppRouteRecord[] = [];

    for (const item of items) {
      // 获取搜索关键词，转换为小写并去除首尾空格
      const searchName = appliedFilters.name?.toLowerCase().trim() || "";
      const searchRoute = appliedFilters.route?.toLowerCase().trim() || "";

      // 获取菜单标题和路径，确保它们存在
      const menuTitle = formatMenuTitle(item.meta?.title || "").toLowerCase();
      const menuPath = (item.path || "").toLowerCase();

      // 使用 includes 进行模糊匹配
      const nameMatch = !searchName || menuTitle.includes(searchName);
      const routeMatch = !searchRoute || menuPath.includes(searchRoute);

      // 如果有子菜单，递归搜索
      if (item.children && item.children.length > 0) {
        const matchedChildren = searchMenu(item.children);
        // 如果子菜单有匹配项，保留当前菜单并更新子菜单
        if (matchedChildren.length > 0) {
          const clonedItem = deepClone(item);
          clonedItem.children = matchedChildren;
          results.push(clonedItem);
          continue;
        }
      }

      // 当前菜单匹配条件则返回
      if (nameMatch && routeMatch) {
        results.push(deepClone(item));
      }
    }

    return results;
  };

  return searchMenu(tableData.value);
});

const isEdit = ref(false);
const formRef = ref<FormInstance>();
const dialogTitle = computed(() => {
  const type = labelPosition.value === "menu" ? "菜单" : "权限";
  return isEdit.value ? `编辑${type}` : `新建${type}`;
});

const showDialog = (type: string, row: AppRouteRecord) => {
  showModel("menu", row, true);
};

const handleChange = () => {};

const submitForm = async () => {
  if (!formRef.value) return;

  await formRef.value.validate(async (valid) => {
    if (valid) {
      try {
        ElMessage.success(`${isEdit.value ? "编辑" : "新增"}成功`);
        dialogVisible.value = false;
      } catch {
        ElMessage.error(`${isEdit.value ? "编辑" : "新增"}失败`);
      }
    }
  });
};

const showModel = (type: string, row?: any, lock: boolean = false) => {
  dialogVisible.value = true;
  labelPosition.value = type;
  isEdit.value = false;
  lockMenuType.value = lock;
  resetForm();

  if (row) {
    isEdit.value = true;
    nextTick(() => {
      // 回显数据
      if (type === "menu") {
        // 菜单数据回显
        form.name = formatMenuTitle(row.meta.title);
        form.path = row.path;
        form.label = row.name;
        form.icon = row.meta.icon;
        form.sort = row.meta.sort || 1;
        form.isMenu = row.meta.isMenu;
        form.keepAlive = row.meta.keepAlive;
        form.isHidden = row.meta.isHidden || true;
        form.isEnable = row.meta.isEnable || true;
        form.link = row.meta.link;
        form.isIframe = row.meta.isIframe || false;
      } else {
        // 权限按钮数据回显
        form.authName = row.title;
        form.authLabel = row.authMark;
        form.authIcon = row.icon || "";
        form.authSort = row.sort || 1;
      }
    });
  }
};

const resetForm = () => {
  formRef.value?.resetFields();
  Object.assign(form, {
    // 菜单
    name: "",
    path: "",
    label: "",
    icon: "",
    sort: 1,
    isMenu: true,
    keepAlive: true,
    isHidden: true,
    link: "",
    isIframe: false,
    // 权限
    authName: "",
    authLabel: "",
    authIcon: "",
    authSort: 1,
  });
};

const deleteMenu = async () => {
  try {
    await ElMessageBox.confirm("确定要删除该菜单吗？删除后无法恢复", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });

    ElMessage.success("删除成功");
  } catch (error) {
    if (error !== "cancel") {
      ElMessage.error("删除失败");
    }
  }
};

const deleteAuth = async () => {
  try {
    await ElMessageBox.confirm("确定要删除该权限吗？删除后无法恢复", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });

    ElMessage.success("删除成功");
  } catch (error) {
    if (error !== "cancel") {
      ElMessage.error("删除失败");
    }
  }
};

// 修改计算属性，增加锁定控制参数
const disableMenuType = computed(() => {
  // 编辑权限时锁定为权限类型
  if (isEdit.value && labelPosition.value === "button") return true;
  // 编辑菜单时锁定为菜单类型
  if (isEdit.value && labelPosition.value === "menu") return true;
  // 顶部添加菜单按钮时锁定为菜单类型
  if (!isEdit.value && labelPosition.value === "menu" && lockMenuType.value)
    return true;
  return false;
});

// 添加一个控制变量
const lockMenuType = ref(false);

const isExpanded = ref(false);
const tableRef = ref();

const toggleExpand = () => {
  isExpanded.value = !isExpanded.value;
  nextTick(() => {
    if (tableRef.value && filteredTableData.value) {
      // 递归处理所有行的展开/收起状态
      const processRows = (rows: AppRouteRecord[]) => {
        rows.forEach((row) => {
          if (row.children && row.children.length > 0) {
            tableRef.value.elTableRef.toggleRowExpansion(row, isExpanded.value);
            processRows(row.children);
          }
        });
      };
      processRows(filteredTableData.value);
    }
  });
};
</script>

<style lang="scss" scoped>
.menu-page {
  .svg-icon {
    width: 1.8em;
    height: 1.8em;
    overflow: hidden;
    vertical-align: -8px;
    fill: currentcolor;
  }

  :deep(.small-btn) {
    height: 30px !important;
    padding: 0 10px !important;
    font-size: 12px !important;
  }
}
</style>
